package com.agileboot.common.utils.file;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.multipart.MultipartFile;

/**
 * 文件类型工具类
 *
 * @author agileboot
 */
public class FileTypeUtil {

    private static final Map<String, String> FILE_TYPE_MAP = new HashMap<>();

    static {
        // 初始化文件头与类型的映射
        // Excel文件
        FILE_TYPE_MAP.put("d0cf11e0", "xls"); // MS Excel
        FILE_TYPE_MAP.put("504b0304", "xlsx"); // MS Excel (OOXML)
        // CSV文件 (CSV没有特定的文件头，通过扩展名判断)
        // 其他常见类型
        FILE_TYPE_MAP.put("ffd8ffe0", "jpg"); // JPEG
        FILE_TYPE_MAP.put("89504e47", "png"); // PNG
        FILE_TYPE_MAP.put("47494638", "gif"); // GIF
        FILE_TYPE_MAP.put("49492a00", "tif"); // TIFF
        FILE_TYPE_MAP.put("41433130", "dwg"); // CAD
        FILE_TYPE_MAP.put("25504446", "pdf"); // Adobe PDF
        FILE_TYPE_MAP.put("7b5c7274", "rtf"); // Rich Text Format
        FILE_TYPE_MAP.put("504b0304", "docx"); // MS Word (OOXML)
        FILE_TYPE_MAP.put("d0cf11e0", "doc"); // MS Word
    }

    private FileTypeUtil() {
    }

    /**
     * 判断文件是否为Excel文件
     *
     * @param file 文件
     * @return 是否为Excel文件
     */
    public static boolean isExcel(MultipartFile file) {
        String extension = getFileExtension(file);
        return "xls".equals(extension) || "xlsx".equals(extension);
    }

    /**
     * 判断文件是否为CSV文件
     *
     * @param file 文件
     * @return 是否为CSV文件
     */
    public static boolean isCsv(MultipartFile file) {
        String extension = getFileExtension(file);
        return "csv".equals(extension);
    }

    /**
     * 获取文件扩展名
     *
     * @param file 文件
     * @return 扩展名
     */
    public static String getFileExtension(MultipartFile file) {
        String originalFilename = file.getOriginalFilename();
        if (StringUtils.isBlank(originalFilename)) {
            return "";
        }
        
        // 优先通过文件名后缀判断
        String extension = FilenameUtils.getExtension(originalFilename).toLowerCase();
        
        // 如果无法通过文件名判断，尝试通过文件头判断
        if (StringUtils.isBlank(extension)) {
            try (InputStream is = file.getInputStream()) {
                String fileHead = getFileHeader(is);
                for (Map.Entry<String, String> entry : FILE_TYPE_MAP.entrySet()) {
                    if (fileHead.startsWith(entry.getKey())) {
                        extension = entry.getValue();
                        break;
                    }
                }
            } catch (IOException e) {
                // 异常时返回空扩展名
                return "";
            }
        }
        
        return extension;
    }

    /**
     * 获取文件头
     *
     * @param is 输入流
     * @return 文件头(16进制字符串)
     * @throws IOException IO异常
     */
    private static String getFileHeader(InputStream is) throws IOException {
        byte[] b = new byte[4];
        if (is.read(b, 0, b.length) != -1) {
            return bytesToHexString(b);
        }
        return "";
    }

    /**
     * 将字节数组转换为16进制字符串
     *
     * @param src 字节数组
     * @return 16进制字符串
     */
    private static String bytesToHexString(byte[] src) {
        StringBuilder builder = new StringBuilder();
        if (src == null || src.length <= 0) {
            return "";
        }
        for (byte b : src) {
            int v = b & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                builder.append(0);
            }
            builder.append(hv);
        }
        return builder.toString().toLowerCase();
    }
} 